package com.roads.project.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.roads.common.constant.Constants;
import com.roads.common.utils.DateUtils;
import com.roads.common.utils.SecurityUtils;
import com.roads.project.domain.ProInstitutionDetail;
import com.roads.project.mapper.ProInstitutionDetailMapper;
import com.roads.project.mapper.ProInstitutionMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.roads.project.mapper.ProPeriodMapper;
import com.roads.project.domain.ProPeriod;
import com.roads.project.service.IProPeriodService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 工期Service业务层处理
 * 
 * @author nhp
 * @date 2021-12-22
 */
@Service
public class ProPeriodServiceImpl implements IProPeriodService {

    @Autowired
    private ProPeriodMapper mapper;

    @Autowired
    private ProInstitutionDetailMapper institutionDetailMapper;

    /**
     * 根据主键ID查询详情
     * 
     * @param id 工期主键
     * @return 工期
     */
    @Override
    public ProPeriod getModelById(Long id) {
        return mapper.getModelById(id);
    }

    /**
     * 根据标段编号和工期名称获取工期详情
     *
     * @param institutionCode 标段编号
     * @param periodName 工期
     * @return 工期详情
     */
    @Override
    public ProPeriod getPeriodByPeriodName(String institutionCode, String periodName) {
        return mapper.getPeriodByPeriodName(institutionCode, periodName);
    }

    /**
     * 获取最后一期
     *
     * @param institutionCode 标段编码
     * @return 最后一期
     */
    @Override
    public ProPeriod getLastPeriod(String institutionCode) {
        return mapper.getLastPeriod(institutionCode);
    }

    /**
     * 获取当前计量期次
     *
     * @param institutionCode 标段编号
     * @return 当前计量期次
     */
    @Override
    public ProPeriod getCurrentPeriod(String institutionCode) {
        return mapper.getCurrentPeriod(institutionCode);
    }

    /**
     * 获取最后锁定期次
     *
     * @param institutionCode 标段编号
     * @return 最后锁定期次
     */
    @Override
    public ProPeriod getLastLockPeriod(String institutionCode) {
        return mapper.getLastLockPeriod(institutionCode);
    }

    /**
     * 根据项目获取当前计量期次，取第一个标段的当前期次
     *
     * @param projectId 项目ID
     * @return 当前计量期次
     */
    @Override
    public ProPeriod getCurrentPeriodByProjectId(Integer projectId) {
        return mapper.getCurrentPeriodByProjectId(projectId);
    }

    /**
     * 查询列表
     * 
     * @param model 工期
     * @return 工期
     */
    @Override
    public List<ProPeriod> selectModelList(ProPeriod model) {
        return mapper.selectModelList(model);
    }

    /**
     * 根据项目ID获取工期，整个项目所有施工标段的去重查询
     *
     * @param projectId 项目ID
     * @return 工期集合
     */
    @Override
    public List<ProPeriod> selectPeriodNameListByProjectId(Integer projectId) {
        return mapper.selectPeriodNameListByProjectId(projectId);
    }

    /**
     * 根据用户获取标段工期，去掉重复工期
     *
     * @param userName 用户名称
     * @return 工期集合
     */
    @Override
    public List<ProPeriod> selectDistinctBidPeriodListByUser(String userName) {
        return mapper.selectDistinctBidPeriodListByUser(userName);
    }

    /**
     * 生成工期
     *
     * @param detail 标段详情
     * @param userName 登录用户名称
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int gen(ProInstitutionDetail detail, String userName) {
        // 先删除标段下的工期
        mapper.deleteByInstitutionCode(detail.getInnerCode());
        // 业务上报日、标段开始日期，标段截止日期
        boolean isNaturalMonth = Constants.YES.equals(detail.getIsNaturalMonth()) ? true : false;
        int businessReportingDate = detail.getBusinessReportingDate();
        Date bidBeginDate = detail.getBeginDate();
        Date bidEndDate = detail.getEndDate();
        int bidEndYear = DateUtils.getYear(detail.getEndDate());
        int bidEndMonth = DateUtils.getMonth(detail.getEndDate());
        List<ProPeriod> periods = new ArrayList<ProPeriod>();
        ProPeriod lastPeriod = null;
        int periodName = 1;
        while (true) {
            // 防止死循环
            if (periodName == 100) {
                break;
            }
            ProPeriod period = new ProPeriod();
            // 第一期
            if (periodName == 1) {
                period.setBeginDate(bidBeginDate);
                if (isNaturalMonth) {
                    // 自然月
                    period.setEndDate(DateUtils.getLastDay(bidBeginDate));
                } else {
                    int beginDateDay = DateUtils.getDay(bidBeginDate);
                    Date endDate = DateUtils.getDate(DateUtils.getYear(bidBeginDate), DateUtils.getMonth(bidBeginDate), businessReportingDate);
                    if (beginDateDay < businessReportingDate) {
                        // 如果开始小于上报日
                        period.setEndDate(endDate);
                    } else {
                        // 如果开始大于上报日
                        period.setEndDate(DateUtils.addMonths(endDate, 1));
                    }
                }
            } else {
                Date lastEndDate = lastPeriod.getEndDate();
                if (lastEndDate.equals(bidEndDate)) {
                    break;
                }
                Date periodBeginDate = DateUtils.addDays(lastEndDate, 1);
                period.setBeginDate(periodBeginDate);

                if (isNaturalMonth) {
                    Date periodEndDate = DateUtils.getLastDay(periodBeginDate);
                    int year = DateUtils.getYear(periodEndDate);
                    int month = DateUtils.getMonth(periodEndDate);
                    if (bidEndYear == year && bidEndMonth == month) {
                        period.setEndDate(bidEndDate);
                    } else {
                        period.setEndDate(periodEndDate);
                    }
                } else {
                    // 项目结束日期
                    int bidEndDay = DateUtils.getDay(bidEndDate);
                    Date periodEndDate = DateUtils.addMonths(lastPeriod.getEndDate(), 1);
                    int lastYear = DateUtils.getYear(lastEndDate);
                    int lastMonth = DateUtils.getMonth(lastEndDate);
                    if (bidEndDay < businessReportingDate && (bidEndYear == lastYear && bidEndMonth == lastMonth + 1)) {
                        period.setEndDate(bidEndDate);
                    } else if (bidEndDay > businessReportingDate && (bidEndYear == lastYear && bidEndMonth == lastMonth)){
                        period.setEndDate(bidEndDate);
                    } else if (periodEndDate.getTime() > bidEndDate.getTime()) {
                        period.setEndDate(bidEndDate);
                    } else {
                        period.setEndDate(periodEndDate);
                    }
                }
            }
            period.setInstitutionCode(detail.getInnerCode());
            period.setYear(String.valueOf(DateUtils.getYear(period.getEndDate())));
            period.setMonth(String.valueOf(DateUtils.getMonth(period.getEndDate()) + 1));
            period.setCreateBy(userName);
            period.setCreateTime(DateUtils.getNowDate());
            period.setPeriodName(String.valueOf(periodName));
            periods.add(period);
            lastPeriod = period;
            periodName++;
        }
        // 批量插入
        mapper.insertBatch(periods);
        return 1;
    }

    /**
     * 新增
     *
     * @param detail 标段详情
     * @param userName 登录用户名称
     * @return 结果
     */
    @Override
    public int insert(ProInstitutionDetail detail, String userName) {
        // 获取标段最后一期
        ProPeriod lastPeriod = mapper.getLastPeriod(detail.getInnerCode());
        // 第一期新增
        ProPeriod period = new ProPeriod();
        boolean isNaturalMonth = Constants.YES.equals(detail.getIsNaturalMonth()) ? true : false;
        // 业务上报日、标段开始日期，标段截止日期
        int businessReportingDate = detail.getBusinessReportingDate();
        Date bidBeginDate = detail.getBeginDate();
        Date bidEndDate = detail.getEndDate();
        if (null == lastPeriod) {
            period.setBeginDate(detail.getBeginDate());
            if (isNaturalMonth) {
                // 如果是自然月
                period.setEndDate(DateUtils.getLastDay(bidBeginDate));
            } else {
                int beginDateDay = DateUtils.getDay(bidBeginDate);
                Date endDate = DateUtils.getDate(DateUtils.getYear(bidBeginDate), DateUtils.getMonth(bidBeginDate), businessReportingDate);
                if (beginDateDay < businessReportingDate) {
                    // 如果开始小于上报日
                    period.setEndDate(endDate);
                } else {
                    // 如果开始大于上报日
                    period.setEndDate(DateUtils.addMonths(endDate, 1));
                }
            }
            period.setPeriodName("1");
        } else {
            // 最后一期的开始日期、截止日期
            Date lastEndDate = lastPeriod.getEndDate();
            Date periodBeginDate = DateUtils.addDays(lastEndDate, 1);
            period.setBeginDate(periodBeginDate);
            int periodName = Integer.parseInt(lastPeriod.getPeriodName());
            // 是否是最后一期增加
            if (lastEndDate.equals(bidEndDate)) {
                if (isNaturalMonth) {
                    Date periodEndDate = DateUtils.getLastDay(periodBeginDate);
                    period.setEndDate(periodEndDate);
                } else {
                    int beginDateDay = DateUtils.getDay(periodBeginDate);
                    Date periodEndDate = DateUtils.getDate(DateUtils.getYear(periodBeginDate), DateUtils.getMonth(periodBeginDate), businessReportingDate);
                    if (beginDateDay < businessReportingDate) {
                        // 如果小于上报日
                        period.setEndDate(periodEndDate);
                    } else {
                        // 如果大于上报日
                        period.setEndDate(DateUtils.addMonths(periodEndDate, 1));
                    }
                }
            } else {
                int bidEndYear = DateUtils.getYear(detail.getEndDate());
                int bidEndMonth = DateUtils.getMonth(detail.getEndDate());
                if (isNaturalMonth) {
                    Date periodEndDate = DateUtils.getLastDay(periodBeginDate);
                    int year = DateUtils.getYear(periodEndDate);
                    int month = DateUtils.getMonth(periodEndDate);
                    if (bidEndYear == year && bidEndMonth == month) {
                        period.setEndDate(bidEndDate);
                    } else {
                        period.setEndDate(periodEndDate);
                    }
                } else {
                    // 项目结束日期
                    int bidEndDay = DateUtils.getDay(bidEndDate);
                    Date periodEndDate = DateUtils.addMonths(lastPeriod.getEndDate(), 1);
                    int lastYear = DateUtils.getYear(lastEndDate);
                    int lastMonth = DateUtils.getMonth(lastEndDate);
                    if (bidEndDay < businessReportingDate && (bidEndYear == lastYear && bidEndMonth == lastMonth + 1)) {
                        period.setEndDate(bidEndDate);
                    } else if (bidEndDay > businessReportingDate && (bidEndYear == lastYear && bidEndMonth == lastMonth)){
                        period.setEndDate(bidEndDate);
                    } else if (lastEndDate.getTime() < bidEndDate.getTime() && periodEndDate.getTime() > bidEndDate.getTime()) {
                        period.setEndDate(bidEndDate);
                    }else {
                        period.setEndDate(periodEndDate);
                    }
                }
            }
            period.setPeriodName(String.valueOf(++periodName));
        }
        period.setInstitutionCode(detail.getInnerCode());
        period.setYear(String.valueOf(DateUtils.getYear(period.getEndDate())));
        period.setMonth(String.valueOf(DateUtils.getMonth(period.getEndDate()) + 1));
        period.setCreateBy(userName);
        period.setCreateTime(DateUtils.getNowDate());
        return mapper.insert(period);
    }

    /**
     * 修改
     * 
     * @param model 工期
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(ProPeriod model) {
        // 工期集合
        List<ProPeriod> updateList = new ArrayList<ProPeriod>();
        // 获取修改工期
        ProPeriod updatePeriod = mapper.getModelById(model.getPeriodId());
        updatePeriod.setEndDate(model.getEndDate());
        System.out.println(SecurityUtils.getUsername());
        updatePeriod.setUpdateBy(SecurityUtils.getUsername());
        updatePeriod.setUpdateTime(DateUtils.getNowDate());
        updatePeriod.setYear(String.valueOf(DateUtils.getYear(updatePeriod.getEndDate())));
        updatePeriod.setMonth(String.valueOf(DateUtils.getMonth(updatePeriod.getEndDate()) + 1));
        updateList.add(updatePeriod);
        ProPeriod lastPeriod = updatePeriod;
        // 获取比当前工期大的工期
        List<ProPeriod> bigPeriodList = mapper.selectBigPeriodList(updatePeriod.getInstitutionCode(), updatePeriod.getPeriodId());
        ProInstitutionDetail detail = institutionDetailMapper.getModelByInnerCode(updatePeriod.getInstitutionCode());
        // 业务上报日、标段开始日期，标段截止日期
        boolean isNaturalMonth = Constants.YES.equals(detail.getIsNaturalMonth()) ? true : false;
        int businessReportingDate = detail.getBusinessReportingDate();
        Date bidEndDate = detail.getEndDate();
        int bidEndYear = DateUtils.getYear(bidEndDate);
        int bidEndMonth = DateUtils.getMonth(bidEndDate);
        for (int i = 0; i < bigPeriodList.size(); i++) {
            ProPeriod period = bigPeriodList.get(i);
            Date periodBeginDate = DateUtils.addDays(lastPeriod.getEndDate(), 1);
            period.setBeginDate(periodBeginDate);
            if (i == 0) {
                if (isNaturalMonth) {
                    period.setEndDate(DateUtils.getLastDay(periodBeginDate));
                } else {
                    // 如果本期的开始日期的天数大于业务上报日，本期的截止日期就是下个月的业务上报日
                    int periodBeginDay = DateUtils.getDay(periodBeginDate);
                    int year = DateUtils.getYear(periodBeginDate);
                    int month = DateUtils.getMonth(periodBeginDate);
                    if (periodBeginDay > businessReportingDate) {
                        period.setEndDate(DateUtils.getDate(year, month + 1, businessReportingDate));
                    } else {
                        period.setEndDate(DateUtils.getDate(year, month, businessReportingDate));
                    }
                }
            } else {
                // 最后一期的开始日期、截止日期
                Date lastEndDate = lastPeriod.getEndDate();
                period.setBeginDate(periodBeginDate);
                // 是否是最后一期增加
                if (lastEndDate.equals(bidEndDate)) {
                    if (isNaturalMonth) {
                        Date periodEndDate = DateUtils.getLastDay(periodBeginDate);
                        period.setEndDate(periodEndDate);
                    } else {
                        int beginDateDay = DateUtils.getDay(periodBeginDate);
                        Date periodEndDate = DateUtils.getDate(DateUtils.getYear(periodBeginDate), DateUtils.getMonth(periodBeginDate), businessReportingDate);
                        if (beginDateDay < businessReportingDate) {
                            // 如果小于上报日
                            period.setEndDate(periodEndDate);
                        } else {
                            // 如果大于上报日
                            period.setEndDate(DateUtils.addMonths(periodEndDate, 1));
                        }
                    }
                } else {
                    if (isNaturalMonth) {
                        Date periodEndDate = DateUtils.getLastDay(periodBeginDate);
                        int year = DateUtils.getYear(periodEndDate);
                        int month = DateUtils.getMonth(periodEndDate);
                        if (bidEndYear == year && bidEndMonth == month) {
                            period.setEndDate(bidEndDate);
                        } else {
                            period.setEndDate(periodEndDate);
                        }
                    } else {
                        // 项目结束日期
                        int bidEndDay = DateUtils.getDay(bidEndDate);
                        Date periodEndDate = DateUtils.addMonths(lastPeriod.getEndDate(), 1);
                        int lastYear = DateUtils.getYear(lastEndDate);
                        int lastMonth = DateUtils.getMonth(lastEndDate);
                        if (bidEndDay < businessReportingDate && (bidEndYear == lastYear && bidEndMonth == lastMonth + 1)) {
                            period.setEndDate(bidEndDate);
                        } else if (bidEndDay > businessReportingDate && (bidEndYear == lastYear && bidEndMonth == lastMonth)){
                            period.setEndDate(bidEndDate);
                        } else {
                            period.setEndDate(periodEndDate);
                        }
                    }
                }
            }
            period.setYear(String.valueOf(DateUtils.getYear(period.getEndDate())));
            period.setMonth(String.valueOf(DateUtils.getMonth(period.getEndDate()) + 1));
            period.setUpdateBy(SecurityUtils.getUsername());
            period.setUpdateTime(DateUtils.getNowDate());
            lastPeriod = period;
            updateList.add(period);
        }
        // 批量修改
        mapper.updateBatch(updateList);
        return 1;
    }

    /**
     * 批量删除
     * 
     * @param ids 主键集合
     * @return 结果
     */
    @Override
    public int deleteByIds(Long[] ids) {
        return mapper.deleteByIds(ids);
    }

    /**
     * 删除
     * 
     * @param id 工期主键
     * @return 结果
     */
    @Override
    public int delete(Long id) {
        return mapper.delete(id);
    }

}
